<template>
  <view id="img" class="lazyload" :style="compStyle">
    <transition :name="loaded ? '' : 'fade'">
      <image
        v-if="loaded"
        v-show="showImg"
        :src="src"
        :alt="alt"
        class="lazyload__img"
        :style="{ width: newWidth, height: newHeight }"
        :mode="mode"
        @load="imgLoad"
      />
    </transition>
    <view
      v-if="!showImg"
      class="lazyload__placeholder"
      :style="{ width: newWidth, height: newHeight }"
    >
      <image
        class="lazyload__placeholder-img"
        src="../static/comps/book-gray.png"
      />
    </view>
  </view>
</template>

<script>
let observer = null;

export default {
  props: {
    compStyle: String,
    src: {
      type: String,
      default: ""
    },
    alt: {
      type: String,
      default: ""
    },
    width: {
      type: Number | String,
      default: "100%"
    },
    height: {
      type: Number | String,
      default: "100%"
    },
    mode: {
      type: String,
      default: ""
    }
  },

  data() {
    return {
      loaded: false, // 是否已经加载
      ready: false // 图片是否已经加载好
    };
    ``;
  },

  computed: {
    newWidth() {
      return typeof this.width === "number" ? `${this.width}px` : this.width;
    },
    newHeight() {
      return typeof this.height === "number" ? `${this.height}px` : this.height;
    },
    showImg() {
      return this.loaded && this.ready;
    }
  },

  watch: {
    loaded(newValue) {
      if (newValue) {
        if (observer) observer.disconnect();
      }
    }
  },

  methods: {
    imgLoad(event) {
      this.ready = true;
    }
  },

  mounted() {
    // app小程序使用createIntersectionObserver实现懒加载
    // #ifndef H5
    try {
      this.$nextTick(() => {
        observer = uni.createIntersectionObserver(this);
        observer.relativeToViewport().observe("#img", res => {
          if (res.intersectionRatio > 0 && !this.loaded) {
            this.loaded = true;
            // 已经展示的图片不再监听滚动了
            if (observer) observer.disconnect();
          }
        });
      });
    } catch (e) {
      //TODO handle the exception
    }
    // #endif
    // h5使用image的onload事件
    // #ifdef H5
    const img = new Image();
    img.src = this.src;
    img.onload = () => {
      this.loaded = true;
    };
    // #endif
  },

  beforeDestroy() {
    if (observer) observer.disconnect();
  }
};
</script>

<style lang="scss">
.lazyload {
  &__img {
    width: 100%;
    height: 100%;
  }

  &__placeholder {
    width: 100%;
    height: 100%;
    background: #ccc;
    display: flex;
    flex-flow: row nowrap;
    justify-content: center;
    align-items: center;

    &-img {
      width: 48rpx;
      height: 48rpx;
    }
  }
}
</style>
